package com.sunday.gateway.mock.web;

import com.sunday.common.core.remoting.rest.page.PageVO;
import com.sunday.common.core.remoting.rest.response.RestResponse;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoServerApi {

    public void printRequest(HttpServletRequest request) {
        log.info("===============================================================================================================================================");
        log.info(request.getRequestURI());
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            log.info("[Head] : {} ==== {}", key, request.getHeader(key));
        }
        /**
         * HttpServletRequest的getParameterMap()方法是用来获取HTTP请求中所有的参数的一个方便的方式，该方法返回一个Map<String, String[]>类型的对象。这个Map的键（key）是请求参数的名字，而值（value）是一个字符串数组（String[]），包含了对应于该参数名的所有值。
         * 例如，在一个HTTP请求中，您可以通过GET或者POST方法传递参数，这些参数可以通过请求的查询字符串（URL中?后面的部分）或表单数据提交（对于POST请求）。
         * 举个例子，假设一个HTTP GET请求的URL如下所示:
         * plaintext
         * http://www.example.com/somepage?param1=value1&param2=value2&param2=value3
         * 当在服务端调用getParameterMap()时，它会返回如下Map:
         * java
         * {
         *   "param1" : ["value1"],
         *   "param2" : ["value2", "value3"]
         * }
         * 在这个Map中，param1有一个值value1，而param2有两个值[value2, value3]，因为param2出现了两次且有不同的值。
         * 这个方法对于确定传递了哪些参数及其值非常有用，特别是在参数名不是预先知道的情况下，您可以遍历Map来处理所有传递的参数及其值。这也适用于POST请求中的表单数据（application/x-www-form-urlencoded类型的POST请求）。如果请求是用multipart/form-data编码的，通常用来上传文件，那么这些方法可能就不适用了，需要其他方式来获取数据。
         */
        request.getParameterMap().forEach((k, v) -> log.info("[Param] : {} ==== {}", k, v));

        /**
         * TODO 后续需要查看流的状况
         * org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#readJavaType(com.fasterxml.jackson.databind.JavaType, org.springframework.http.HttpInputMessage)
         */
        StringBuilder requestBody = new StringBuilder();
        String line;

        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                requestBody.append(line).append('\n');
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 现在 requestBody.toString() 包含了请求体的内容
        String bodyContent = requestBody.toString();
        log.info("[Body] : {}", bodyContent);

    }

    @GetMapping("/page")
    public RestResponse page(HttpServletRequest request) {
        printRequest(request);
        PageVO pageVO = PageVO.of(1, 10);
        pageVO.setRecords(Arrays.asList(new User("zhangsan", 18, "123"), new User("zhangsan", 18, "123"), new User("zhangsan", 18, "123")));
        log.info("release >================");
        return RestResponse.ok(pageVO);
    }

    @GetMapping("/list")
    public RestResponse list(HttpServletRequest request) {
        printRequest(request);
        log.info("release >================");
        return RestResponse.ok(Arrays.asList(LocalDateTime.now(), LocalDateTime.now(), LocalDateTime.now()));
    }

    @GetMapping("/get")
    public RestResponse get(HttpServletRequest request) {
        printRequest(request);
        log.info("release >================");
        return RestResponse.ok(new User("zhangsan", 18, "123"));
    }

    @PostMapping("/postFit")
    public RestResponse postFit(HttpServletRequest request) {
        printRequest(request);
        log.info("release >================");
        return RestResponse.ok(request.getRequestURI());
    }

    @GetMapping("/fit/{time}")
    public RestResponse fit(HttpServletRequest request, @PathVariable("time") String time) throws InterruptedException {
        printRequest(request);
        log.info("==========> time : {}", time);
        TimeUnit.SECONDS.sleep(Long.valueOf(time));
        log.info("release >================");
        return RestResponse.ok(request.getRequestURI());
    }

    @GetMapping("/fallback")
    public RestResponse fallback(HttpServletRequest request) {
        printRequest(request);
        return RestResponse.ok(request.getRequestURI());
    }

    @GetMapping("/statusCodes")
    public ResponseEntity statusCodes(HttpServletRequest request) {
        printRequest(request);
//        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
        return ResponseEntity.status(HttpStatus.PERMANENT_REDIRECT).build();
    }

    @GetMapping("/redirectTo")
    public RestResponse redirectTo(HttpServletRequest request) {
        printRequest(request);
        return RestResponse.ok(request.getRequestURI());
    }

    @GetMapping("/setPath/redirectTo")
    public RestResponse setPath(HttpServletRequest request) {
        printRequest(request);
        return RestResponse.ok(request.getRequestURI());
    }


    @GetMapping("/301")
    public ResponseEntity status301(HttpServletRequest request) {
        printRequest(request);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Location", "https://www.baidu.com/");
        return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY).headers(headers).build();
    }


}